   *******************************************************
   *                                                     *
   * MICROSOFT BASIC PATCHES ON V 1.0                    *
   *                                                     *
   * RESULTING IN V 3.0                                  *
   *                                                     *
   * PATCHES 4 - 7 - 83                                  *
   *******************************************************
   ;
 ORG $405E  ; START OF INITIALISATION
   ;
   ; DEFINES
   ;
   ; *****************************************************
   ;
   ; CONSTANTS
   ;
CTRLD * $04 ;  CNTRL/D = PAGE TOGGLE
CTRLP * $10 ;  CNTRL/P = PRINTER TOGGLE
LF * $0A ; LINEFEED
FF * $0C ; FORMFEED
PAGLIN * $0C ; 12 LINES PER PAGE
   ;
   ; *****************************************************
   ;
   ; ZERO PAGE 
   ;
OUTENA * $0014 ; OUTPUT ENABLE
NULL * $0015 ; NR OF NULLS AFTER LF
LNLNGT * $0017 ; LINELENGTH
COMFLD * $0018 ; LAST COMMA FIELD
PTRL * $0019 ; POINTER
PTRH * $001A ;
STRDES * $0063 ; STRING DESCRIPTOR
PRGBGL * $0078 ; BEGIN OF BASIC WORKSPACE
PRGBGH * $0079 ;
STRPTL * $0080 ; LOWEST MEMORY USED BY STRINGS
STRPTH * $0081 ;
HIMEML * $0084 ; HIGHEST MEMORY USED BY BASIC
HIMEMH * $0085 ;
LINENR * $0086 ; LINE NUMBER
DIRECT * $0087 ; ALSO DIRECT FLAG IF $FF
GARB * $00A0 ; GARBAGE COLLECTION DESCRIPTOR
JMPFN * $00A1 ; JUMP FOR FUNCTION CALLS
FLPAD * $00B5 ; FLP PADDING
CURNXT * $00BF ; CURRENT/NEXT ROUTINE
TXTPTL * $00C7 ; POINTER TO CURRENT/NEXT CHARACTER
TXTPTH * $00C8 ;
   ;
   ; *****************************************************
   ;
   ; INTERNAL BASIC ROUTINES
   ;
CHRNXT * $00C0 ; GET NEXT CHARACTER ROUTINE
GETCUR * $00C6 ; GET CURRENT CHARACTER ROUTINE
   ;
AROVCK * $22F2 ; ARRAY AREA OVERFLOW CHECK
ERROR * $2321 ; ERROR ROUTINE
COLD * $2348 ; COLD ENTRY POINT OF BASIC
COLDPR * $2351 ; COLD START OF BASIC
NEW * $2523 ; NEW COMMAND
ENDSTP * $26ED ; END/STOP ROUTINE
GOTO * $27F5 ; ROUTINE FOR GOTO AND GOSUB
COLECT * $28B8 ; COLLECT NR IN 19,1A
CRLF * $29BF ; OUTPUT CR AND LF
GETADR * $2C34 ; GET ADDRESS IN FLP FROM EXPRESSION
PRTSTR * $2A18 ; PRINT STRING , POINTED BY A,X
GETLIN * $2AB0 ; GET INPUT
SYNERR * $2D99 ; SYNTAX ERROR
CONV * $35EF ; CONVERT FLP TO INTEGER IN (11,12)
PRIAX * $3C59 ; PRINT NUMBER IN A,X AS DECIMAL
CRNXTR * $4040 ; CURRENT/NEXT ROUTINE COPY
   ;
   ; *****************************************************
   ;
   ; EXTERNAL SYSTEM ROUTINES
   ;
GETCH * $0475 ; INPUT CHARACTER FROM PARALLEL KEYBOARD
OUTCH * $0500 ; OUTPUT CHARACTER TO VIDEOTERMINAL
OUTPR * $0418 ; OUTPUT CHARACTER TO PRINTER
ENAPRT * $04A9 ; ENABLE PRINTER
   ; 
   ;
   ; *****************************************************
   ;
   ; PATCH FOR BREAK 
   ; PARALLEL KEYBOARD CONNECTED TO $1740 PIA
   ; STROBE IN BIT 7
   ;
   ; PATCH IN BASIC
   ; $26DA AD 40 17  LDA $1740
   ;       29 7F     ANDIM $7F
   ;       18  CLC
   ;       EA EA EA EA UNTIL $26E6
   ; *****************************************************
   ;
   ; NEW INITIALIZATION ROUTINE
   ; REPLACES OLD SELF DESTRUCTIVE
   ; PATCH IN BASIC :
   ; $234E 20 18 2A  JSR PRTSTR
   ;
   ; ZEROPAGE LOCATIONS 00 - 09 NOT USED ANYMORE BY BASIC
   ;
START LDXIM $FF ; INITIALIZE STACK POINTER
 TXS  ;
 STX DIRECT ; BEGIN WITH DIRECT MODE
 LDAIM $4C ; SET JUMP CODE FOR FUNCTIONS
 STA JMPFN ;
 LDAIM $48 ; DEFAULT LINELENGTH 72 CHARACTERS
 STA LNLNGT ;
 LDAIM $38 ; DEFAULT LAST COMMA FIELD
 STA COMFLD ;
 LDXIM $1C ; COPY CURRENT/NEXT CHARACTER ROUTINE TO ZP
MOVLP LDAAX CRNXTR ;
 STAZX CURNXT ; STORE ON ZP
 DEX  ;
 BNE MOVLP ;
 TXA  ; SAVE ZERO IN A
 STA FLPAD ; SET PADDING OF FLOATING POINT
 STA $0065 ;
 STA NULL ; DEFAULT NULLS = 0
 STA TRFLAG ; NO TRACE
 STA STFLAG ; NO SINGLE STEP
 STA PRTFLG ; NO PRINTER YET
 STA PAGFLG ; NO PAGE MODE
 PHA  ; PUSH ZERO ON STACK
 STA OUTENA ; ENABLE OUTPUT
 LDAIM $03 ; 
 STA GARB ; SET GARBAGE COLL DESCR TO 3
 LDAIM FF ;  PRINT FORMFEED TO CLEAR SCREEN
 JSR OUTCH ; AND INITIALISE VIDEO ROUTINES
 JSR CRLF ; PRINT CRLF ON TERMINAL
 LDXIM $66 ; STRING DESCRIPTOR
 STX STRDES ;
 LDAIM HELLOMS ; PRINT 'MICROSOFT BASIC V 3.0'
 LDYIM HELLOMS /
 JSR PRTSTR ;
MEMINP LDAIM MEMSIZ ; PRINT 'MEMORY END
 LDYIM MEMSIZ /
 JSR PRTSTR ;
 JSR GETLIN ; GET INPUT
 STX TXTPTL ; POINTER TO INPUT
 STY TXTPTH ;
 JSR CHRNXT ; GET CHARACTER
 TAY  ; SAVE A IN Y
 BNE NOTDEF ; IF NOT 0 THEN NOT DEFAULT 
 LDAIM END ;
 LDYIM END / END OF BASIC CODE IS BEGIN OF WORKSPACE
 STA PTRL ;  SEARCH POINTER IN RAM
 STY PTRH ;
 LDYIM $00 ;
NXTRAM INC PTRL ; POINTER = POINTER + 1  IN RAM
 BNE NOHPTR ;
 INC PTRH ;
NOHPTR LDAIM $55 ; STORE VALUE IN RAM
 STAIY PTRL ;
 CMPIY PTRL ; CAN IT BE STORED ?
 BNE FNDEND ; END OF RAM FOUND
 ASLA  ; CHANGE VALUE TO BE STORED , TRY OTHER BITS
 STAIY PTRL ;
 CMPIY PTRL ; CAN IT ALSO BE STORED ?
 BNE FNDEND ;
 BEQ NXTRAM ; ALWAYS 
NOTDEF JSR GETCUR ; GET CURRENT CHARACTER FROM INPUT
 JSR COLECT ; COLLECT NR 
 TAY  ;
 BEQ FNDEND ; NO ERROR ?
 BNE MEMINP ; IF ERROR ASK AGAIN
FNDEND LDA PTRL ; STORE END OF RAM IN HIMEM OF BASIC
 LDY PTRH ;
 STA HIMEML ;
 STY HIMEMH ;
 STA STRPTL ; SET ALSO STRING POINTER
 STY STRPTH ;
 LDXIM END ;
 LDYIM END / SET BEGIN OF WORKSPACE POINTER
 STX PRGBGL ;
 STY PRGBGH ;
 LDYIM $00 ; SET DUMMY END OF PROGRAM
 TAY  ;
 STAIY PRGBGL ;
 INC PRGBGL ;
 BNE NOHPR ;
 INC PRGBGH ; PROGRAM BEGIN = PROGRAM BEGIN + 1
NOHPR LDA PRGBGL ;
 LDY PRGBGH ;
 JSR AROVCK ; GET NEW POINTERS TO PROGRAM
 JSR CRLF ; PRINT CRLF
 LDA HIMEML ; CALCULATE FREE BYTES
 SEC  ;
 SBC PRGBGL ;
 TAX  ; 
 LDA HIMEMH ;
 SBC PRGBGH ;
 JSR PRIAX ; PRINT FREE BYTES
 LDAIM BYTFRE ;
 LDYIM BYTFRE / PRINT 'BYTES FREE'
 JSR PRTSTR ;
 JSR NEW ; DO NEW COMMAND
 JMP COLD ;
   ;
   ; *****************************************************
   ;
   ; ENABLE BLANKS AFTER LINE NUMBER AND BEFORE STATEMENT
   ;
   ; PATCH IN BASIC
   ; $236A 20 .. ..  JSR BLANKS
   ;
   ; THE DATA READ HAS A BUG NOW AND CAN BE IMPROVED BY
   ; PATCH IN BASIC
   ; $2B7C 20 48 28 JSR $2848  ADD OFFSET TO CURR CHAR PTR
   ; $2B7F 20 C6 00 JSR GETCUR
   ; $2B82 C9 83    CMP $83    IS IT DATA STATEMENT ?
   ;
BLANKS JSR COLECT ; ORIGINAL CODE, GET LINENR
 LDX TXTPTL ; POINTER IN INPUT BUFFER
BLLOOP DEX  ; ONE BACK IN BUFFER
 LDAZX $00,X ; IS THERE A BLANK ?
 CMPIM $20 ; IF BLANK THEN
 BEQ BLLOOP ;  GO FURTHER BACK
 INX  ; ONE TOO FAR
 STX TXTPTL ; STORE POINTER TO FIRST BLANK
 RTS  ;
   ;
   ; *****************************************************
   ;
   ; SINGLE STEP AND TRACE PATCH
   ; ENABLES TO SINGLE STEP OR TRACE A BASIC PROGRAM
   ; STEPS ARE BASIC LINES
   ;
   ; PATCH IN BASIC :
   ; $26A1 20 .. .. JSR TRACE
   ; 
   ; TRACE AAN : POKE 16942,1
   ;       UIT : POKE 16942,0
   ; STEP  AAN : POKE 16943,1
   ;       UIT : POKE 16943,0
   ;
TRACE LDA DIRECT ; IF DIRECT NO ACTION TRACE OR SINGLESTEP 
   ;
 CMPIM $FF ;
 BEQ NORUN ;
 LDA TRFLAG ; TRACE WANTED ?
 BEQ STEP ; IF NOT TRY SINGLE STEP
 LDX LINENR ; PRINT LINE NUMBER
 LDA DIRECT ;
 JSR PRIAX ;
 JSR CRLF ;
 JMP STEP  ; TRY STEP
STEP LDA STFLAG ; STEP WANTED ?
 BEQ NORUN ;
 JSR GETCH ;
 CMPIM 'S ; KEY 'S' IS STOP
 BNE NORUN ;
 SEC  ; JUMP TO STOP ROUTINE
 JMP ENDSTP ;
NORUN JSR GETCUR ; ORIGINAL BASIC CODE
 RTS  ;
   ;
   ; *****************************************************
   ;
   ; MEMORY AND STACK OVERFLOW MUST GIVE DIFFERENT
   ; ERROR MESSAGES
   ;
   ; PATCH IN BASIC :
   ; $21AE 53 54 41 43 4B 20 4D 45 4D 4F
   ;       52 59 20 4F 56 45 52 46 4F D7
   ; THIS TEXT IS :
   ; MEMORY OVERFLOW
   ; STACK MEMORY OVERFLOW
   ; $2320 4B
   ; $22E8 20 .. .. JSR ERRSTA
   ; $379D 52
   ;
ERRSTA BCS STAERR ; STACK ERROR ?
 STA $006F ;
 TSX  ; TEST STACK
 CPX $006F ;
ERRST BCC STAERR ;
 RTS  ;
STAERR LDXIM $45 ; ERROR STACK NUMBER
 JMP ERROR ; ERROR ROUTINE
   ;
   ; *****************************************************
   ;
   ; THE PROMPT 'OK' IS REPLACED BY THE CHARACTER '>'
   ; WITHOUT CRLF
   ; ALSO AFTER ENETRING A LINE THE '>' APPEARS NOW
   ; THE '>' MEANS THAT BASIC IS WAITING FOR INPUT
   ;
   ; PATCH IN BASIC :
   ; $2267 3E 00
   ; $235D EC
   ; $2400 4C .. .. JMP PROMPT
   ;
PROMPT LDAIM '> ; LOAD PROMPT CHARACTER
 JSR OUTCH ; PRINT IT
 JMP COLDPR ; START BASIC AGAIN
   ;
   ; *****************************************************
   ;
   ; CASSETTE READ AND WRITE PATCH TO ROUTINES OF
   ; SEBO WOLDRINGH PLACED AT $0200 - $0400
   ;
   ; PATCH IN BASIC :
   ; $275C 4C 24 02
   ; $27A3 4C 00 02 JMP READ
   ;       EA EA    NOP
   ;                NOP UNTIL $27B4
   ; $27B5 A2 FF    LDXIM $FF
   ;       9A       TXS
   ;
   ; READ AND WRITE ROUTINES ADAPTED FOR CONTROL VIA 
   ; PB2 = WRITE
   ; PB3 = READ
   ; PATCH IN READ AND WRITE ROUTINES THEREFORE :
   ; $0236 A9 0C
   ; $023E A9 0C LDAIM $0C
   ; $0294 A9 $FB
   ; $0294 A9 FB
   ; $0312 A9 04
   ; $031B A9 F7
   ; $0386 A9 08
   ;
   ; *****************************************************
   ;
   ; CALCULATED LINENUMBERS IN GOSUB OR GOTO STATEMENTS
   ; ARE POSSIBLE WITH THE FOLLOWING PATCH
   ; BESIDES A ABSOLUTE LINENUMBER IT IS NOW ALSO 
   ; POSSIBLE TO USE A VARIABLE ( POSITIVE INTEGER )
   ;
   ; PATCH IN BASIC :
   ; $27F2 4C .. .. JMP CALCLN
   ;
CALCLN BCS CALC ; IF FIRST CHAR NOT NUMBER THEN CALCULATE
 JSR COLECT ; GET LINENR ( ORIGINAL CODE )
 JMP GOTO ; CONTINUE ORIGINAL CODE FOR BASIC JUMP
CALC JSR GETADR ; GET ADDRESS IN FLP
 JSR CONV ; CONVERT TO INTEGER IN 11,12 ( AS COLECT DOES )
 JMP GOTO ; CONTINUE SAME AS NORMAL LINENUMBER GIVEN
   ;
   ; *****************************************************
   ;
   ; BASIC CAN BE SPEEDED UP BY USING THE ROR INSTRUCTION
   ;
   ; PATCH IN BASIC :
   ; $ 37C2 76 02  BCS $37DC
   ;
   ; $ 37D1 76 02  ROR $02,X
   ;        76 03  ROR $03,X
   ;        76 04  ROR $04,X
   ;        68     PLA
   ;        6A     ROR A
   ;        C8     INY
   ;        D0 E8  BNE $37C4
   ;        18     CLC
   ;        60     RTS
   ;
   ; $38C3  66 73  ROR $73
   ;        66 74  ROR $74
   ;        66 75  ROR $75
   ;        66 76  ROR $76
   ;        66 BD  ROR $BD
   ;        98     TAY
   ;        4A     LSR A
   ;        D0 D6  BNE $38A7
   ;        60     RTS
 
   ;
   ; *****************************************************
   ;
   ; INPUT TO BASIC
   ;
   ; INPUT TO GET STATEMENT
   ; CHARACTER FROM KEYBOARD WITHOUT ECHO
   ;
   ; PATCH IN BASIC :
   ; $2AE5 20 75 04  JSR GETCH
   ;
   ; NORMAL INPUT WITH ECHO
   ; CHECK FOR CTRL/D = TOGGLE PAGE MODE
   ; CHECK FOR CTRL/P = TOGGLE PRINTER OUTPUT MODE
   ;
   ; PATCH IN BASIC :
   ; $2456 20 .. ..  JSR INPUT
   ; $2A51 20 .. ..  JSR OUTPUT
   ;
INPUT JSR GETCH ; GET CHARACTER FROM KEYBOARD
 CMPIM CTRLP ; IS IT PRINTER TOGGLE CTRL/P ?
 BEQ PRT ;
 CMPIM CTRLD ; IS IT PAGE TOGGLE CNTRL/D ?
 BEQ PAGE ;
 JSR OUTPUT ; NORMAL ECHO
 RTS  ;
   ;
PRT LDA PRTFLG ; IS PRINTER ENABLED ?
 BEQ ENPRT ; NO ENABLE PRINTER
 LDAIM $00 ;
 STA PRTFLG ; DISABLE PRINTER
 BEQ INPUT ; ALWAYS
ENPRT JSR ENAPRT ; ENABLE PRINTER
 LDAIM $FF ;
 STA PRTFLG ; SET PRINT FLAG
 JMP INPUT ;
   ;
PAGE LDA PAGFLG ; IS PAGE MODE ENABLED ?
 BEQ ENPAG ;
 LDAIM $00 ;
 STA PAGFLG ; DISABLE PAGE MODE
 BEQ INPUT ; ALWAYS 
ENPAG LDAIM PAGLIN ; SET NUMBER OF LINES ON A PAGE
 STA PAGFLG ;
 STA LINCNT ; 
 BNE INPUT ; ALWAYS
   ;
OUTPUT CMPIM LF ; LINEFEED OUTPUT ?
 BNE NOLF ;
 PHA  ; SAVE A
 LDA PAGFLG ; PAGE MODE ?
 BEQ NOPAG ;
 DEC LINCNT ; ONE MORE LINE
 BNE NOPAG ; NOT END OF PAGE
 LDAIM PAGLIN ; SET PAGE COUNT TO MAXIMUM
 STA LINCNT ;
 JSR GETCH ; GET KEYBOARD
 CMPIM CTRLD ; END OF PAGE MODE ?
 BNE NOPAG ;
 LDAIM $00 ; RESET PAGE MODE
 STA PAGFLG ;
NOPAG PLA  ; RESTORE CHARACTER
NOLF JSR OUTCH ; OUTPUT CHRACTER TO VIDEO
 PHA  ;
 LDA PRTFLG ; PRINTER ENABLED ?
 BNE NOPRT ;
 PLA  ;
 RTS  ;
NOPRT PLA  ;
 JSR OUTPR ; PRINTER OUTPUT
 RTS  ;
   ;
   ;
   ; *****************************************************
   ;
   ; MESSAGES :
   ;
HELLOMS = $0D
 = $0A
 = 'M
 = 'I
 = 'C
 = 'R
 = 'O
 = 'S
 = 'O
 = 'F
 = 'T
 = ' 
 = 'B
 = 'A
 = 'S
 = 'I
 = 'C
 = ' 
 = 'V
 = ' 
 = '3
 = '.
 = '0
 = $0D 
 = $0A
 = $00
   ;
MEMSIZ = 'M
 = 'E
 = 'M
 = 'O
 = 'R
 = 'Y
 = ' 
 = 'E
 = 'N
 = 'D
 = ' 
 = $00 
   ;
BYTFRE = ' 
 = 'B
 = 'Y
 = 'T
 = 'E
 = 'S
 = ' 
 = 'F
 = 'R
 = 'E
 = 'E
 = $0D 
 = $0A
 = $00
   ;
TRFLAG = $00 ; TRACE FLAG
STFLAG = $00 ; SINGLE STEP FLAG
PRTFLG = $00 ; PRINTER FLAG
PAGFLG = $00 ; PAGE FLAG
LINCNT = $00 ; LINE COUNT USED FOR PAGE MODE
END = $00
